#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   EditSource
@Time    :   2023/04/02 15:03:57
@author  :   Eval
@Version :   1.0
@Describe:   素材编辑器
'''


from PySide6.QtCore import (QMetaObject, QRect,QSize, Qt,QObject,QTimer)
from PySide6.QtGui import (QPixmap,QCloseEvent)
from PySide6.QtWidgets import (QWidget,QLineEdit,QCheckBox,QComboBox,QTabWidget,QPlainTextEdit)
from uuid import uuid4

from conf.Edit.MyLael import *
from conf.Edit.MyCanvasWidget import *
from conf.GameLogin import *
from conf.Edit.SaveJson import save as JsonSave
# from lib.scripts.GC import *

class EditSourceUI(QWidget):
    def __init__(self,form):
        super(EditSourceUI,self).__init__()
        self.ui = SourceUI(self)
        self.setMinimumSize(QSize(550, 430))
        self.setMaximumSize(QSize(550, 430))
        self.setWindowTitle("素材编辑器")
        self.setWindowIcon(QPixmap("lib/images/editIco_1.png"))
        self.setStyleSheet("background-color:rgb(255,255,255)")
        self.form:MyWidget = form
        self.ui.setupUi(self)

        self.BlockInfo = None
        # 存储复制的id
        self.saveBID = ""

    def showUI(self,lab:QLabel=None,MIndex=0):
        if lab is None:
            self.form.ui.ShowDiaLog_Window("未将对象引用设置到对象的实例",2)
            return
        
        # 缓存的键
        Key = f"{lab.objectName()}-{MIndex}"
        pix = self.form.GC.GameSurfaceCache.get(Key)
        if pix is None:
            self.ui.pixC = self.form.GC.GameSurfaceCache.get(lab.objectName())
            self.ui.pixC = QPixmap(f'lib/images/{lab.objectName()}.png')
            pix = self.ui.pixC.copy(0,MIndex*32,32,32).scaled(50,50)
            self.form.GC.GameSurfaceCache[Key] = pix
            # 将原始的素材也备份一份,防止从单帧的素材切换到多帧图块时,播放动画会错乱
            self.form.GC.GameSurfaceCache[lab.objectName()] = self.ui.pixC
        # 从缓存里面取出来
        self.ui.pixC = self.form.GC.GameSurfaceCache[lab.objectName()]
        # 设置预览图
        self.ui.selectPreView.setPixmap(pix)
        self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
        self.setWindowFlags(Qt.WindowType.Widget)

        # 获取到图块的属性
        self.BlockInfo = self.form.SourceCache.get(Key)
        if self.BlockInfo is None:
            self._setAttributeData(MIndex,lab)
        else:
            self._setAttributeData(MIndex)
        self.show()
    
    def closeEvent(self, event: QCloseEvent) -> None:
        print_info("关闭资源编辑器")
        if self.ui.qTime.isActive():
            self.ui.playPreViewAnim_fun()
        self.hide()
        return super().closeEvent(event)

    def _setAttributeData(self,MIndex=None,lab=None):
        # 清空子组件残留的值
        self.ui.resetUI(self)
        if self.BlockInfo is None:
            self.BlockInfo = {}
            self.BlockInfo["animMax"] = lab.animMax
            self.ui.msgContrl.setText(f"当前图块还未注册,请点击生成按钮")
        if not lab is None:
            self.BlockInfo["type"] = lab.objectName()
        if not MIndex is None:
            # 是当前选中的图块位于整个资源图片的位置,并不代表再地图中渲染的key
            self.BlockInfo["index"] = MIndex

        self.ui.BtnPlayAnim.setVisible(True)

        # 根据选中的图块设置编辑器的默认值,, 如果这个默认值为空,且输入框内有值, 那么就使用输入框内已经输入的值,  否则就使用 self.BlockInfo提供的数据
        def setData(control:QObject,DataKey:str):
            # 如果没有这个属性
            if self.BlockInfo.get(DataKey) is None:
                if type(control) == QLineEdit:
                    return control.text()
                elif type(control) == QPlainTextEdit:
                    return control.toPlainText()
                elif type(control) == QCheckBox:
                    return False
                elif type(control) == QComboBox:
                    return "null"
            if type(self.BlockInfo.get(DataKey)) != bool:
                return str(self.BlockInfo.get(DataKey))
            return self.BlockInfo.get(DataKey)

        self.ui.LB_ID.setText(setData(self.ui.LB_ID,"id"))
        self.ui.LB_Index.setText(setData(self.ui.LB_Index,"key"))
        self.ui.LB_Name.setText(setData(self.ui.LB_Name,"name"))
        self.ui.LB_Anim.setText(setData(self.ui.LB_Anim,"animMax"))
        self.ui.CB_Type.setCurrentText(setData(self.ui.CB_Type,"type"))
        if self.BlockInfo.get("type") == "enemys":
            self.ui.tabWidget.setCurrentIndex(1)
            self.ui.TE_Des.setPlainText(setData(self.ui.TE_Des,"describe"))
            self.ui.LE_HP.setText(setData(self.ui.LE_HP,"hp"))
            self.ui.LE_Atk.setText(setData(self.ui.LE_Atk,"atk"))
            self.ui.LE_Def.setText(setData(self.ui.LE_Def,"def"))
            self.ui.LE_Money.setText(setData(self.ui.LE_Money,"money"))
            self.ui.LE_Exp.setText(setData(self.ui.LE_Exp,"exp"))
            self.ui.LE_Skill.setText(setData(self.ui.LE_Skill,"skill"))
            self.ui.LE_Speed.setText(setData(self.ui.LE_Speed,"speed"))
            

        elif self.BlockInfo.get("type") == "items":
            self.ui.tabWidget.setCurrentIndex(2)
            self.ui.IItem_Des.setPlainText(setData(self.ui.IItem_Des,"describe"))
            self.ui.IItem_EquipData.setPlainText(setData(self.ui.IItem_EquipData,"equipData"))
            self.ui.IItem_ShowBag.setChecked(setData(self.ui.IItem_ShowBag,"showBag"))
            self.ui.IItem_Money.setText(setData(self.ui.IItem_Money,"money"))
            self.ui.IItem_Num.setText(setData(self.ui.IItem_Num,"number"))
            self.ui.IItem_NumMax.setText(setData(self.ui.IItem_NumMax,"maxNum"))
            self.ui.IItem_Type.setCurrentText(setData(self.ui.IItem_Type,"IType"))
            self.ui.IItem_Value.setText(setData(self.ui.IItem_Value,"value"))
            
            self.ui.IItem_Script.setCurrentText(self.ui.scripts[setData(self.ui.IItem_Script,"script")])

        else:
            self.ui.tabWidget.setCurrentIndex(0)
            self.ui.TE_DoorInfo.setPlainText(setData(self.ui.TE_DoorInfo,"doorInfo"))
            self.ui.CB_CanPass.setChecked(setData(self.ui.CB_CanPass,"canPass"))
            self.ui.CM_Trigger.setCurrentText(setData(self.ui.CM_Trigger,"trigger"))
            self.ui.CM_TriggerKey.setText(setData(self.ui.CM_TriggerKey,"triggerKey"))
        # 如果放当前图块的动画帧数 不大于0,隐藏播放动画按钮
        if not int(self.ui.LB_Anim.text()):
            self.ui.BtnPlayAnim.setVisible(False)

        # 如果没有id那么认为本条注册的资源注册数据不正确,禁止使用 保存按钮, 激活 生成按钮, 一键生成索引以及使用 uuid生成的随机id
        if self.BlockInfo.get("id") is None:
            self.ui.BtnSave.setEnabled(False)
            self.ui.BtnCopyID.setEnabled(False)
            self.ui.BtnNew.setEnabled(True)
            
        else:
            self.ui.BtnSave.setEnabled(True)
            self.ui.BtnCopyID.setEnabled(True)
            self.ui.BtnNew.setEnabled(False)

        self.ui.BtnPasteID.setEnabled(False if self.saveBID == "" else True)
        # # 停止动画的播放
        if self.ui.qTime.isActive():
            self.ui.playPreViewAnim_fun()
        # self.ui.qTime.stop()

class SourceUI(object):
    def __init__(self,form:EditSourceUI) -> None:
        self.form = form
        self.preIndex = 0
        self.pixC = None
        self.qTime = QTimer()
        self.qTime.timeout.connect(self.playPreViewAnim)
        self.scripts = {
            "null":"无",
            "monsterBook":"怪物手册",
            "addM":"增加金币",
            "addExp":"增加经验",
        }
        
    def setupUi(self, Form:EditSourceUI):
        # 保存/关闭按钮
        self.BtnNew = Form.form.ui.createBtnBox("生成",350,10,40,25,form=Form,event=self.newSource)
        self.BtnCopyID = Form.form.ui.createBtnBox("复制key",430,10,50,25,form=Form,event=self.CopyID,eventArgs="copy")
        self.BtnSave = Form.form.ui.createBtnBox("保存",410,50,40,25,form=Form,event=self.saveSource)
        self.BtnClose = Form.form.ui.createBtnBox("关闭",480,50,40,25,form=Form,event=self.closeUI)
        self.BtnPlayAnim = Form.form.ui.createBtnBox("播放动画",370,100,75,25,form=Form,event=self.playPreViewAnim_fun,MW=75)
        # 预览图
        Form.form.ui.createLab("当前编辑",460,85,form=self.form)
        self.selectPreView = Form.form.ui.createLab(None,460,110,50,50,form=self.form)

        self.LB_ID = Form.form.ui.createLineBox(20, 15, 260, 21,form=Form,labName="图块ID")
        self.LB_ID.setEnabled(False)  # id字段不可手动修改
        self.LB_Index = Form.form.ui.createLineBox(20, 50, 113, 21,form=Form,labName="图块索引")
        self.LB_Index.setEnabled(False)   # 索引不可手动修改,由编辑器根据最大的图块索引进行自动递增
        self.LB_Name = Form.form.ui.createLineBox(220, 50, 113, 21,form=Form,labName="图块名称")
        self.CB_Type = Form.form.ui.createComboBox(20, 90, 113, 21,form=Form,array=["terrains","animates","enemys", "npcs","items"],labName="图块类别")
        self.LB_Anim = Form.form.ui.createLineBox(220,90, MW=50,form=Form,labName="动画帧数")
        self.LB_Anim.setEnabled(False)   # 帧数不可手动修改,由全局配置文件设定

        
        self.tabWidget = QTabWidget(Form)
        self.tabWidget.setGeometry(QRect(5, 150, 540, 240))
        # 普通页
        self.tab = QWidget()
        self.TE_DoorInfo = Form.form.ui.createPlainTextBox(10, 10, 285, 71,form=self.tab,labName="门信息")
        self.CB_CanPass = Form.form.ui.createCheckBox(10, 100, 16, 20,form=self.tab,labName="可通行性")
        self.CM_Trigger = Form.form.ui.createComboBox(10,130,array=["null","openDoor","pushBox"],form=self.tab,labName="触发器")
        
        Form.form.ui.createLab("触发条件(id)",110, 100, 51, 16,self.tab)
        self.CM_TriggerKey = Form.form.ui.createLineBox(180,100,form=self.tab)
        # Form.form.ui.createComboBox(150,100,array=["null","openDoor","pushBox"],form=self.tab)
        self.BtnPasteID = Form.form.ui.createBtnBox("粘贴id",290,95,50,25,MW=50,form=self.tab,event=self.CopyID,eventArgs="paste")

        self.tabWidget.addTab(self.tab, "普通图块")
        # 敌人页
        self.tab_2 = QWidget()
        self.TE_Des = Form.form.ui.createPlainTextBox(10, 5, 271, 51,form=self.tab_2,labName="怪物描述")
        self.LE_HP = Form.form.ui.createLineBox(10, 70, form=self.tab_2,labName="生命值")
        self.LE_Atk = Form.form.ui.createLineBox(10, 100, form=self.tab_2,labName="攻击力")
        self.LE_Def = Form.form.ui.createLineBox(10, 135, form=self.tab_2,labName="防御力")
        self.LE_Speed = Form.form.ui.createLineBox(10, 170, form=self.tab_2,labName="速 度")
        self.LE_Money = Form.form.ui.createLineBox(180, 75, form=self.tab_2,labName="金币")
        self.LE_Exp = Form.form.ui.createLineBox(180, 105,form=self.tab_2,labName="经验")
        self.LE_Skill = Form.form.ui.createLineBox(180, 140,value=-1,form=self.tab_2,labName="技能")
        self.tabWidget.addTab(self.tab_2, "怪物")

        # 道具页
        self.tab_3 = QWidget()
        self.IItem_Des = Form.form.ui.createPlainTextBox(5, 5, 275, 51,form=self.tab_3,labName="道具描述")
        self.IItem_EquipData = Form.form.ui.createPlainTextBox(5, 60, 275, 41,form=self.tab_3,labName="道具的\n装备属性")
        self.IItem_ShowBag = Form.form.ui.createCheckBox(5, 120, 16, 20,form=self.tab_3,isChecked=False,labName="不显示在背包")
        self.IItem_Money = Form.form.ui.createLineBox(360, 10, 113, 21,value=1,form=self.tab_3,labName="金币")
        self.IItem_Num = Form.form.ui.createLineBox(360, 50, 113, 21,value=1,form=self.tab_3,labName="数量")
        self.IItem_NumMax = Form.form.ui.createLineBox(120, 120, 113, 21,value=1,form=self.tab_3,labName="数量上限")
        self.IItem_Type = Form.form.ui.createComboBox(335,90,array=["items","constants","tools","equips"],form=self.tab_3,labName="道具类型")
        self.IItem_Value = Form.form.ui.createLineBox(360, 120, 113, 21,value=1,form=self.tab_3,labName=" 值")
        self.IItem_Script = Form.form.ui.createComboBox(335,160,array=self.scripts.values(),form=self.tab_3,labName="执行脚本")

        self.tabWidget.addTab(self.tab_3, "道具")
        self.tabWidget.setCurrentIndex(2)
        # 显示一些操作之后的信息
        self.msgContrl = Form.form.ui.createLab(None,5,400,300,16,Form)
        QMetaObject.connectSlotsByName(Form)

    def saveSource(self):
        """保存资源数据"""
        self.form.BlockInfo["name"] = self.LB_Name.text()
        self.form.BlockInfo["animMax"] = self.LB_Anim.text()
        # 默认尺寸暂时就写死为32x32吧
        self.form.BlockInfo["rect"] = [32,32]

        if self.form.BlockInfo.get("id") is None:
            self.form.BlockInfo["id"] = self.LB_ID.text()
            

        if self.form.BlockInfo.get("type") == "enemys":
            self.form.BlockInfo["describe"] = self.TE_Des.toPlainText()
            self.form.BlockInfo["hp"] = self.LE_HP.text()
            self.form.BlockInfo["atk"] = self.LE_Atk.text()
            self.form.BlockInfo["def"] = self.LE_Def.text()
            self.form.BlockInfo["money"] = self.LE_Money.text()
            self.form.BlockInfo["exp"] = self.LE_Exp.text()
            self.form.BlockInfo["skill"] = self.LE_Skill.text()
            self.form.BlockInfo["speed"] = self.LE_Speed.text()

        elif self.form.BlockInfo.get("type") == "items":
            self.form.BlockInfo["describe"] = self.IItem_Des.toPlainText()
            self.form.BlockInfo["equipData"] = self.IItem_EquipData.toPlainText()
            self.form.BlockInfo["showBag"] = self.IItem_ShowBag.isChecked()
            self.form.BlockInfo["money"] = self.IItem_Money.text()
            self.form.BlockInfo["number"] = self.IItem_Num.text()
            self.form.BlockInfo["value"] = self.IItem_Value.text()

            sName = ""
            for s in self.scripts:
                if self.scripts[s] == self.IItem_Script.currentText():
                    sName = s
                    break
            self.form.BlockInfo["script"] = sName
            # 如果道具的类型是  constants 和 equips ,那么最大数量只能是 1
            IType = self.IItem_Type.currentText()
            self.form.BlockInfo["IType"] = IType
            if IType == "constants" or IType == "equips":
                self.IItem_NumMax.setText("1")
            self.form.BlockInfo["maxNum"] = self.IItem_NumMax.text() 
        else:
            self.form.BlockInfo["doorInfo"] = self.TE_DoorInfo.toPlainText()
            self.form.BlockInfo["canPass"] = self.CB_CanPass.isChecked()
            self.form.BlockInfo["trigger"] = self.CM_Trigger.currentText()
            self.form.BlockInfo["triggerKey"] = self.CM_TriggerKey.text()
            
        self.form.form.SourceMgr[str(self.form.BlockInfo["key"])] = self.form.BlockInfo
        if self.form.form.SourceCache.get(f"{self.form.BlockInfo.get('type')}-{self.form.BlockInfo['index']}") is None:
            # 注册之后写入缓存, 立刻就能使用
            self.form.form.SourceCache[f"{self.form.BlockInfo.get('type')}-{self.form.BlockInfo['index']}"] = self.form.form.SourceMgr[str(self.form.form.SourceMaxKey)]
            self.form.form.SourceMaxKey += 1 # 将当前的最大值key +1.
            self.msgContrl.setText(f"注册图块:{self.LB_Index.text()} 成功")
        else:
            self.msgContrl.setText(f"更新图块:{self.LB_Index.text()} 成功")
            
        with open("conf/Source.json","w",encoding="utf8") as f:
            f.write(JsonSave(self.form.form.SourceMgr).replace("False","false").replace("True","true"))
            # json.dump(self.form.form.SourceMgr,f,indent=4,ensure_ascii=False)
        

    def newSource(self):
        """生成资源数据"""
        if self.form.BlockInfo.get("id") is None:
            self.form.BlockInfo["id"] = str(uuid4())
        if self.form.BlockInfo.get("key") is None:
            self.form.BlockInfo["key"] = str(self.form.form.SourceMaxKey)
        if self.form.BlockInfo.get("name") is None:
            self.form.BlockInfo["name"] = "新图块"
        self.msgContrl.setText(f"生成图块数据成功,请记得保存噢.")
        self.form._setAttributeData()

    def closeUI(self):
        """不销毁编辑器, 仅隐藏"""
        self.form.hide()

    def resetUI(self,control:QWidget):
        """清空组件残留的值"""
        childrens = control.children()
        self.msgContrl.clear()
        for child in childrens:
            if type(child) == QLineEdit:
                child.setText("")
            elif type(child) == QPlainTextEdit:
                child.setPlainText("")
            # 如果这个子组件下面还有子组件, 那么执行递归清空
            if len(child.children()) > 0:
                self.resetUI(child)

    def playPreViewAnim_fun(self):
        """调用预览图块的动画方法"""
        if self.qTime.isActive():
            self.preIndex = 0
            pix = self.pixC.copy(0,int(self.form.BlockInfo["index"])*32,32,32).scaled(50,50)
            # 设置预览图
            self.selectPreView.setPixmap(pix)
            self.qTime.stop()
            self.BtnPlayAnim.setText("播放动画")
            return
        self.BtnPlayAnim.setText("停止动画")
        self.qTime.start(200)
        

    def playPreViewAnim(self):
        """播放预览图块的动画"""
        self.preIndex = (self.preIndex +1) % int(self.LB_Anim.text())
        pix = self.pixC.copy(self.preIndex*32,int(self.form.BlockInfo["index"])*32,32,32).scaled(50,50)
        # 设置预览图
        self.selectPreView.setPixmap(pix)

    def CopyID(self,EType):
        """复制/粘贴当前图块的Key"""
        if EType == "copy":
            self.form.saveBID = self.form.BlockInfo.get("key")
            self.BtnPasteID.setEnabled(True)
            self.msgContrl.setText(f"复制Key:{self.form.saveBID} 完成.")
        else:
            self.CM_TriggerKey.setText(self.form.saveBID)
            self.msgContrl.setText(f"粘贴Key:{self.form.saveBID} 完成.")